// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

#ifndef YOLOV8_SEG_H
#define YOLOV8_SEG_H

#include <opencv2/core/core.hpp>

#include <net.h>
#include <string>
class  point{
public:
    int x;
    int y;
    int cluster=0;
    int pointType=1;//1 noise 2 border 3 core
    int pts=1;//points in MinPts
    std::vector<int> corepts;
    int visited = 0;
    point (){}
    point (float a,float b,int c){
        x = a;
        y = b;
        cluster = c;
    }
};

struct Object
{
    cv::Rect_<float> rect;
    int label;
    float prob;
    cv::Mat mask;
    cv::Mat boxMask;
    std::vector<float> mask_feat;
    std::vector<cv::Point> minbox;
};
struct oil_return{
    std::string suggestion;
    double level;
    int status_code;
    std::string describe;
    std::string serverity;
};
struct sensitive_return{
    std::string suggestion;
    double level;
    int status_code;
    std::string describe;
    std::string serverity;
};
struct GridAndStride
{
    int grid0;
    int grid1;
    int stride;
};
struct  totalInfo   //总体指标
{
    int  hairNum;//毛发总数
    double hairDensity;//平均毛发数
    double meanDiameter;  //平均直径
    int  unitNum;//毛囊总数
    double unitDensity;//平均毛囊数

};
struct  hairInfo   //单个头发
{
    int  hairIndex; //头发index
    double  Diameter;   //直径
    double  length;   //头发长度
    cv::Point hairFoot ; //发根点
    cv::Point hairIndia; //发梢点
    cv::Point hairCenter; //头发重心
    std::vector<cv::Point> hairCnt;//头发轮廓 最小外接矩形
};
struct  unitInfo   //毛囊单元
{
    int unitIndex;  //毛囊index
    std::vector<hairInfo> hairlist; //头发列表
    cv::Point unitPoint  ; //单元毛囊的重心
    cv::Rect unitCnt;//毛囊轮廓
};
class Yolo
{
public:
    Yolo();

    int load(const char* modeltype, int target_size, const float* mean_vals, const float* norm_vals, bool use_gpu = false);

    int load(AAssetManager* mgr, const char* modeltype, int target_size, const float* mean_vals, const float* norm_vals, bool use_gpu = false);

    int detect(const cv::Mat& rgb, std::vector<Object>& objects);

    int draw(cv::Mat& rgb, const std::vector<Object>& objects,double &s);
    void DrawPred(cv::Mat& img,std::vector<Object> result,std::vector<std::string> classNames, std::vector<cv::Scalar> color, const std::vector<unitInfo>& unitinfo);
    void info_init(cv::Mat& img, std::vector<Object>& result, std::vector<unitInfo>& unitinfo, std::vector<hairInfo>& hairinfo,const float& ratio);
    void info_make(std::vector<hairInfo>& hairinfo,std::vector<unitInfo>& unitinfo,totalInfo& totalinfo ,float Eps,int MinPts);
private:
    ncnn::Net yolo;

    int target_size;
    float mean_vals[3];
    float norm_vals[3];
    int image_w;
    int image_h;
    int in_w;
    int in_h;

    ncnn::UnlockedPoolAllocator blob_pool_allocator;
    ncnn::PoolAllocator workspace_pool_allocator;
};

#endif // YOLOV8_SEG_H
